import { Component, NgZone, ViewChild, OnInit, Inject } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material';
// import { CdkTextareaAutosize } from '@angular/cdk/text-field';
// import { take } from 'rxjs/operators';
import { TranslateService } from '@ngx-translate/core';
import { RestService } from '../../services/rest.service';
import { ActionTypes } from '../../models/wdl-types';

import * as _ from 'lodash';

@Component({
  selector: 'app-institution-dialog',
  templateUrl: './institution-dialog.component.html',
  styleUrls: ['./institution-dialog.component.css']
})
export class InstitutionDialogComponent implements OnInit {
  formGroup: FormGroup;
  item: any;
  title = '';
  error = '';

  // could be add, modify
  mode = ActionTypes.ADD;
  disabled = false;
  keyDisabled = false;

  // used to check if instName has changed in modify mode
  oldInstName = '';

  // @ViewChild('autosize') autosize: CdkTextareaAutosize;

  constructor(@Inject(MAT_DIALOG_DATA) private dialogData: any,
              public dialogRef: MatDialogRef<InstitutionDialogComponent>,
              fb: FormBuilder,
              private ngZone: NgZone,
              private translate: TranslateService,
              private rest: RestService,
              private dialog: MatDialog) {
    this.item = dialogData.item;
    this.mode = dialogData.mode;

    if (this.mode === ActionTypes.ADD) {
      this.title = this.translate.get('add')['value'] + this.translate.get('institution')['value'];

      this.formGroup = fb.group({
        instName: [ '', [ Validators.required, Validators.maxLength(128) ] ],
        ip: [ '', [ Validators.required, Validators.minLength(1), Validators.maxLength(10) ] ],
        username: [ '', [ Validators.required, Validators.maxLength(64) ] ],
        password: [ '', [ Validators.required, Validators.minLength(3) ] ],
      });
    } else if (this.mode === ActionTypes.MODIFY) {
      this.keyDisabled = true;
      this.title = this.translate.get('edit')['value'];
      this.oldInstName = this.item['instName'];

      this.formGroup = fb.group({
        instName: [ { value: '', disabled: false}, [ Validators.required ] ],
        ip: [ '', [ Validators.required ] ]
      });

      _.forEach(this.formGroup.controls, (value, key) => {
        value.value = this.item[key];
      });
    }
  }

  isAdd() {
    return this.mode === ActionTypes.ADD;
  }

  /*
  triggerResize() {
    // Wait for changes to be applied, then trigger textarea resize.
    this.ngZone.onStable.pipe(take(1)).subscribe(() => this.autosize.resizeToFitContent(true));
  }
  */

  disableSubmit() {
    return this.formGroup.invalid || (this.mode === ActionTypes.MODIFY && !this.formGroup.dirty);
  }

  isInstNameUsed(insts, name) {
    return _.findIndex(insts, {instName: name}) > -1;
  }

  submit() {
    if (this.mode === ActionTypes.ADD) {
      this.submit4Add();
    } else {
      this.error = '';
      const name = _.trim(this.formGroup.controls.instName.value);
      const ip = _.trim(this.formGroup.controls.ip.value);

      if (name !== this.oldInstName) {
        // check if new instName exists
        this.rest.get('data/institution/search/name?name=' + name).subscribe(data => {
          if (this.isInstNameUsed(data['_embedded']['institutions'], name)) {
            this.error = 'instNameExists';
          } else {
            this.doSubmit();
          }
        }, () => {
          this.error = 'validateInstNameFailed';
        });
      } else {
        // only IP changes
        this.rest.get('data/institution/search/ip?ip=' + ip).subscribe(data => {
          if (data['_embedded']['institutions'].length > 0) {
            this.error = 'instPrefixExists';
          } else {
            this.doSubmit();
          }
        }, () => {
          this.error = 'validatePrefixFailed';
        });
      }
    }
  }

  submit4Add() {
    this.error = '';
    const name = _.trim(this.formGroup.controls.instName.value);
    const ip = _.trim(this.formGroup.controls.ip.value);

    // check if instName is used
    this.rest.get('data/institution/search/name?name=' + name).subscribe(data => {
      if (this.isInstNameUsed(data['_embedded']['institutions'], name)) {
        this.error = 'instNameExists';
      } else {
        // check if user exists
        this.rest.get('api/keycloak/validate/' + _.trim(this.formGroup.controls.username.value)).subscribe(resp => {
          if (resp['status'] === 404) {
            // check if ip exists
            this.rest.get('data/institution/search/ip?ip=' + ip).subscribe(resp2 => {
              if (resp2['_embedded']['institutions'].length > 0) {
                this.error = 'instPrefixExists';
              } else {
                this.doSubmit();
              }
            }, () => {
              this.error = 'validatePrefixFailed';
            });
          } else {
            this.error = 'adminUserExists';
          }
        }, () => {
          this.error = 'validateUserFailed';
        });
      }
    }, () => {
      this.error = 'validateInstNameFailed';
    });
  }

  doSubmit() {
    const data = {};
    _.forEach(this.formGroup.value, (value, key) => {
      if (key !== 'password') {
        data[key] = _.trim(value);
      } else {
        data[key] = value;
      }
    });

    this.dialogRef.close(data);
  }

  ngOnInit() {
  }
}
